﻿using System;
using FireStarterModeller.BO;
using FireStarterModeller.Test.BO;
using FireStarterModeller.UI.LookupLists;
using Habanero.Base.Exceptions;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using NUnit.Framework;

namespace FireStarterModeller.Test.UI.LookupLists
{
    [TestFixture]
    public class TestSimpleLookupListControl
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            UITestUtils.SetupFixture();
        }

        [SetUp]
        public virtual void SetupTest()
        {
            UITestUtils.SetupTest();
        }

        private static IControlFactory CreateControlFactory()
        {
            return new ControlFactoryWin();
        }

        [Test]
        public void Test_Construct()
        {
            //---------------Set up test pack-------------------
            IControlFactory controlFactory = CreateControlFactory();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(controlFactory);
            //---------------Test Result -----------------------
            Assert.AreSame(controlFactory, simpleLookupListControl.ControlFactory);
            Assert.IsInstanceOf(typeof (ILookupListControl), simpleLookupListControl);
        }

        [Test]
        public void Test_Construct_WhenNullControlFactorySet_ShouldThrowException()
        {
            //---------------Set up test pack-------------------
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            try
            {
                SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(null);
                Assert.Fail("expected ArgumentNullException");
            }
            //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("Value cannot be null", ex.Message);
                StringAssert.Contains("controlFactory", ex.ParamName);
            }
            //---------------Test Result -----------------------
        }

        [Test]
        public void Test_Layout()
        {
            //---------------Set up test pack-------------------
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(CreateControlFactory());
            //---------------Test Result -----------------------
            Assert.AreEqual(1, simpleLookupListControl.Controls.Count);
            IEditableGridControl listItemsGridControl = TestUtilsShared.AssertIsInstanceOf<IEditableGridControl>(simpleLookupListControl.Controls[0]);
            Assert.AreEqual(3, listItemsGridControl.Grid.Columns.Count); //First Column is the ID Column
            Assert.AreEqual("Display", listItemsGridControl.Grid.Columns[1].HeaderText);
            Assert.AreEqual("Value", listItemsGridControl.Grid.Columns[2].HeaderText);
        }

        [Test]
        public void Test_LookupTypeName_ShouldReturn_Simple()
        {
            //---------------Set up test pack-------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(CreateControlFactory());
            const string actual = "Simple";
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            string lookupTypeName = simpleLookupListControl.LookupTypeName;
            //---------------Test Result -----------------------
            Assert.AreEqual(lookupTypeName, actual);
        }

        [Test]
        public void Test_Property_GetAndSet()
        {
            //---------------Set up test pack-------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(CreateControlFactory());
            DMProperty dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty();
            //---------------Assert Precondition----------------
            Assert.IsNull(simpleLookupListControl.Property);
            //---------------Execute Test ----------------------
            simpleLookupListControl.Property = dmProperty;
            //---------------Test Result -----------------------
            Assert.IsNotNull(simpleLookupListControl.Property);
            Assert.AreEqual(dmProperty, simpleLookupListControl.Property);
        }

        [Test]
        public void Test_Property_WhenSet_WithMatchingLookupListType_ShouldUseDmPropLookupList()
        {
            //---------------Set up test pack-------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(CreateControlFactory());
            DMProperty dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty();
            DMLookupListSimple dmLookupListSimple = TestUtilsDMLookupListSimple.CreateSavedDMLookupListSimple();
            dmProperty.LookupList = dmLookupListSimple;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            simpleLookupListControl.Property = dmProperty;
            //---------------Test Result -----------------------
            DMLookupList dmLookupList = simpleLookupListControl.LookupList;
            Assert.IsInstanceOf(typeof(DMLookupListSimple),dmLookupList);
            Assert.AreEqual(dmProperty.LookupList,dmLookupList);
        }

        [Test]
        public void Test_Property_WhenSet_WithMatchingLookupListType_GridShouldContainLookupListListItems()
        {
            //---------------Set up test pack-------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(CreateControlFactory());
            DMProperty dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty();
            DMLookupListSimple dmLookupListSimple = TestUtilsDMLookupListSimple.CreateSavedDMLookupListSimple();
            dmLookupListSimple.ListItems.CreateBusinessObject();
            dmLookupListSimple.ListItems.CreateBusinessObject();
            dmLookupListSimple.ListItems.CreateBusinessObject();
            dmProperty.LookupList = dmLookupListSimple;
            //---------------Assert Precondition----------------
            Assert.AreEqual(4, dmLookupListSimple.ListItems.Count);
            //---------------Execute Test ----------------------
            simpleLookupListControl.Property = dmProperty;
            //---------------Test Result -----------------------
            IEditableGridControl listItemsGridControl = TestUtilsShared.AssertIsInstanceOf<IEditableGridControl>(simpleLookupListControl.Controls[0]);
            Assert.AreSame(dmLookupListSimple.ListItems, listItemsGridControl.BusinessObjectCollection);
        }

        [Test]
        public void Test_Property_WhenSet_WithOtherLookupListType_ShouldCreateNewLookupList()
        {
            //---------------Set up test pack-------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(CreateControlFactory());
            DMProperty dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty();
            dmProperty.LookupList = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            //---------------Assert Precondition----------------
            //---------------Execute Test ---------------------
            simpleLookupListControl.Property = dmProperty;
            //---------------Test Result -----------------------
            DMLookupList dmLookupList = simpleLookupListControl.LookupList;
            Assert.AreNotSame(dmProperty.LookupList,dmLookupList);
            Assert.IsInstanceOf(typeof(DMLookupListSimple),dmLookupList);
        }

        [Test]
        public void Test_Property_WhenSet_WithOtherLookupListType_GridShouldContainNewLookupListListItems()
        {
            //---------------Set up test pack-------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(CreateControlFactory());
            DMProperty dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty();
            DMLookupListBusinessObject lookupListBusinessObject = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            dmProperty.LookupList = lookupListBusinessObject;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            simpleLookupListControl.Property = dmProperty;
            //---------------Test Result -----------------------
            IEditableGridControl listItemsGridControl = TestUtilsShared.AssertIsInstanceOf<IEditableGridControl>(simpleLookupListControl.Controls[0]);
            DMLookupListSimple lookupListSimple = (DMLookupListSimple)simpleLookupListControl.LookupList;
            Assert.AreSame(lookupListSimple.ListItems, listItemsGridControl.BusinessObjectCollection);
        }    
        
        [Test]
        public void Test_Property_WhenSetWithOtherLookupListType_ThenSetWithOtherLookupListType_ShouldCreateNewLookupList()
        {
            //---------------Set up test pack-------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(CreateControlFactory());
            DMProperty dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty();
            DMProperty dmProperty2 = TestUtilsDMProperty.CreateUnsavedValidDMProperty();
            dmProperty.LookupList = TestUtilsDMBusinessObjectLookupList.CreateUnsavedValidDMBusinessObjectLookupList();
            simpleLookupListControl.Property = dmProperty;
            DMLookupList dmLookupList = simpleLookupListControl.LookupList;
            //---------------Assert Precondition----------------
            Assert.AreNotSame(dmProperty.LookupList, dmLookupList);
            Assert.IsInstanceOf(typeof(DMLookupListSimple), dmLookupList);
            //---------------Execute Test ---------------------
            simpleLookupListControl.Property = dmProperty2;
            //---------------Test Result -----------------------
            DMLookupList dmLookupList2 = simpleLookupListControl.LookupList;
            Assert.AreNotSame(dmProperty2.LookupList, dmLookupList2);
            Assert.AreNotSame(dmLookupList, dmLookupList2);
            Assert.IsInstanceOf(typeof(DMLookupListSimple), dmLookupList2);
        }

        [Test]
        public void Test_Property_WhenSetWithOtherLookupListType_ThenSetWithMatchingLookupListType_ShouldUseSecondDMPropLookupList()
        {
            //---------------Set up test pack-------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(CreateControlFactory());
            DMProperty dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty();
            DMProperty dmProperty2 = TestUtilsDMProperty.CreateUnsavedValidDMProperty();
            DMLookupListSimple dmLookupListSimple = TestUtilsDMLookupListSimple.CreateSavedDMLookupListSimple();
            dmProperty2.LookupList = dmLookupListSimple;
            simpleLookupListControl.Property = dmProperty;
            DMLookupList dmLookupList = simpleLookupListControl.LookupList;
            //---------------Assert Precondition----------------
            Assert.AreNotSame(dmProperty.LookupList, dmLookupList);
            Assert.IsInstanceOf(typeof(DMLookupListSimple), dmLookupList);
            //---------------Execute Test ---------------------
            simpleLookupListControl.Property = dmProperty2;
            //---------------Test Result -----------------------
            DMLookupList dmLookupList2 = simpleLookupListControl.LookupList;
            Assert.AreSame(dmProperty2.LookupList, dmLookupList2);
            Assert.AreNotSame(dmLookupList, dmLookupList2);
            Assert.IsInstanceOf(typeof(DMLookupListSimple), dmLookupList2);
           
        }

        [Test]
        public void Test_Property_WhenSetToNull_ShouldDisableAndHaveNullLookupList()
        {
            //---------------Set up test pack-------------------
            SimpleLookupListControl simpleLookupListControl = new SimpleLookupListControl(CreateControlFactory());
            DMProperty dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty();
            simpleLookupListControl.Property = dmProperty;
            //---------------Assert Precondition----------------
            IEditableGridControl listItemsGridControl = TestUtilsShared.AssertIsInstanceOf<IEditableGridControl>(simpleLookupListControl.Controls[0]);
            Assert.AreSame(dmProperty, simpleLookupListControl.Property);
            Assert.IsTrue(listItemsGridControl.Enabled);
            //---------------Execute Test ----------------------
            simpleLookupListControl.Property = null;
            //---------------Test Result -----------------------
            Assert.IsNull(simpleLookupListControl.Property);
            Assert.IsNull(simpleLookupListControl.LookupList);
            Assert.IsFalse(listItemsGridControl.Enabled);
        }

        // - Should display UIPanel with the correct fields
        // - When the DM Prop is set:
        //    - if the DmProp.LookupList is of the same type, then the control should return this LUL for the LookupList Property
        //    - if the DmProp.LookupList is of a different type, then the control should return a new LUL for the LookupList Property
        //    - When the Property is set must always return a new SimpleLookupList if the Property.LookupList is not SimpleLookupList
        //    - Throw Exception when null
        //    - When Property is set and is not SimpleLookupList then return new SimpleLookupList but if Property is set again 
        //       and Property.LookupList is SimpleLookupList then must return Property.LookupList
    }
}
